#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import sys

debug_level = False

unixbench_items = [
# seq: match_name,
"Dhrystone 2 using register variables",
"Double-Precision Whetstone",
"Execl Throughput",
"File Copy 1024 bufsize 2000 maxblocks",
"File Copy 256 bufsize 500 maxblocks",
"File Copy 4096 bufsize 8000 maxblocks",
"Pipe Throughput",
"Pipe-based Context Switching",
"Process Creation",
"Shell Scripts (1 concurrent)",
"Shell Scripts (8 concurrent)",
"System Call Overhead",
"System Benchmarks Index Score"
]
data_output = {}

def save_data(line, cur_cpus, item):
    name="_"
    name = name.join(item.split())
    _key = "{0}_{1}".format(cur_cpus, name)
    _index = line.split()[-1]
    _type = "save"
    if _key not in data_output:
        data_output[_key] = []
        _type = "new "
    data_output[_key].append(_index)
    if debug_level is True:
        print("[{2}] {0:>5} {1}".format( _key, _index, _type))

def is_matched(line):
    for item in unixbench_items:
        if item in line:
            return True,item
    return False,None

def get_unixbench_data(file, cur_cpus):
    if debug_level is True:
        print("get_unixbench_data: {1}: {0}".format(cur_cpus, file))

    heade1_found = False
    heade2_found = False
    match_str1 = "CPUs in system; running {0} parallel ".format(cur_cpus)
    match_str2_full = "System Benchmarks Index Values"
    match_str2_part = "System Benchmarks Partial Index"
    match_end = "System Benchmarks Index Score"
    with open(file) as f:
        for line in f:
            line = line.strip('\n')
            if heade1_found is True and heade2_found is True:
                ret, item = is_matched(line)
                if ret is True:
                    save_data(line, cur_cpus, item)
                    if match_end in line:
                        return

            if heade1_found is True:
                if match_str2_full in line or match_str2_part in line:
                    heade2_found = True
                    continue

            if match_str1 in line:
                heade1_found = True
                continue

def show_data():
    if debug_level is True:
        print("\n-------- output single --------\n")
    for i in data_output:
        _data = data_output[i]
        if debug_level is True:
            print("{0}(bigger better) | {1}".format(i, _data))
            if "System Benchmarks Index Score" in i:
                print("")

def get_cpu_num(file):
    cpu_num = []
    with open(file) as f:
        for line in f:
            if "CPUs in system; running " in line:
                cur_cpu = line.split()[5]
                cpu_num.append(cur_cpu)
    
    if 1 <= len(cpu_num) <= 2:
        return cpu_num
    else:
        print("log_file: {0} invalid unixbench log".format(file))
        sys.exit(1)

def analyze_log(file):
    cpus = get_cpu_num(file)
    for cur_cpus in cpus:
        get_unixbench_data(file, cur_cpus)
    show_data()

def handler_data():
    if debug_level is True:
        print("\n-------- output all --------\n")
    for seq in data_output:
        avg = 0
        total = 0
        print("\n%-41s bigger_better  " % (seq), end='')
        _data = data_output[seq]
        count = len(_data)
        for i in _data:
            print(" %10s " % (i), end='')
            total += float(i)
        avg = float(total / count)
        print(" %10.1f " % (avg), end='')
        for i in _data:
            i_flux = float('%.0f' % (float(abs((float(i) - avg) * 100 / avg))))
            print(" %6.0f%%" % i_flux, end='')
    #print("\n")

def init(dbg):
    global debug_level
    debug_level = dbg
    return analyze_log, handler_data
